/*
 * kWatchDog.cpp
 *
 *  Created on: Mar 15, 2012
 *      Author: kylintse
 */

#include "kWatchDog.h"

#define KWATCHDOG_PRECISION	100

kWatchDog::kWatchDog(QObject *parent/*=0*/)
	: QThread(parent)
{
	m_curId=0;
}

kWatchDog::~kWatchDog()
{
	qDeleteAll(m_watchDogs);
}

qint32 kWatchDog::registerWatchDog(const QString& name,quint32 time)
{
	qint32 id=m_curId.fetchAndAddOrdered(1);

	kWatchDogItem* item=new kWatchDogItem;
	item->name=name;
	item->time=time;
	item->counter=0;
	m_lockWatchDog.lock();
	m_watchDogs.insert(id,item);
	m_lockWatchDog.unlock();
	return id;
}

void kWatchDog::unregisterWatchDog(qint32 id)
{
	QMutexLocker lock(&m_lockWatchDog);
	if(m_watchDogs.contains(id))
	{
		delete m_watchDogs.value(id);
		m_watchDogs.remove(id);
	}
}

void kWatchDog::resetWatchDog(qint32 id)
{
	QMutexLocker lock(&m_lockWatchDog);
	if(m_watchDogs.contains(id))
	{
		m_watchDogs.value(id)->counter=0;
	}
}

void kWatchDog::watchDogTimer()
{
	QMutexLocker lock(&m_lockWatchDog);
	QMap<qint32,kWatchDogItem*>::const_iterator i=m_watchDogs.constBegin();
	while(i!=m_watchDogs.constEnd())
	{
		i.value()->counter++;
		if(i.value()->counter>=(i.value()->time/KWATCHDOG_PRECISION))
		{
			qWarning()<<i.value()->name<<" watch dog timeout";
			quit();
		}
		i++;
	}
}

void kWatchDog::run()
{
	QTimer* timerWatchDog=new QTimer;
	connect(timerWatchDog,SIGNAL(timeout()),this,SLOT(watchDogTimer()),
			Qt::DirectConnection);

	timerWatchDog->start(KWATCHDOG_PRECISION);

	exec();

	timerWatchDog->stop();
	delete timerWatchDog;
}
